package com.cxz.kotlin.baselibs.base

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import android.provider.Settings
import android.view.*
import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.cxz.kotlin.baselibs.R
import com.cxz.kotlin.baselibs.utils.AppManager
import com.cxz.kotlin.baselibs.utils.CommonUtil
import com.cxz.kotlin.baselibs.utils.KeyBoardUtil
import com.cxz.kotlin.baselibs.utils.StatusBarUtil
import com.cxz.kotlin.baselibs.widget.CustomAlertDialog
import com.fphoenixcorneae.util.toast.ToastUtil
import com.tbruyelle.rxpermissions3.RxPermissions
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.functions.Consumer
import org.greenrobot.eventbus.EventBus
import java.io.Serializable
import java.util.concurrent.TimeUnit

/**
 * @author chenxz
 * @date 2018/11/19
 * @desc BaseActivity
 */
abstract class BaseActivity : AppCompatActivity() {

    /**
     * 布局文件id
     */
    @LayoutRes
    protected abstract fun attachLayoutRes(): Int

    /**
     * 初始化数据
     */
    open fun initData() {}

    /**
     * 初始化 View
     */
    abstract fun initView()

    /**
     * 开始请求
     */
    abstract fun start()

    /**
     * 是否使用 EventBus
     */
    open fun useEventBus(): Boolean = false

    /**
     * 获取权限处理类
     */
    protected val rxPermissions: RxPermissions by lazy {
        RxPermissions(this)
    }

    /**
     * 设置状态栏的背景颜色
     */
    fun setStatusBarColor(@ColorInt color: Int) {
        StatusBarUtil.setColor(this, color, 0)
    }

    /**
     * 设置状态栏图标的颜色
     *
     * @param dark true: 黑色  false: 白色
     */
    fun setStatusBarIcon(dark: Boolean) {
        if (dark) {
            StatusBarUtil.setLightMode(this)
        } else {
            StatusBarUtil.setDarkMode(this)
        }
    }
    private val rp: RxPermissions by lazy {
        RxPermissions(this)
    }
    private val locationDialog: CustomAlertDialog by lazy {
        CustomAlertDialog(this)
    }
    private var disposableLocationRequest: Disposable? = null
    protected var permissinAllow = false
    protected var isClickBack = false
    private var timerDis: Disposable? = null


     fun timer() {
        Observable.timer(3, TimeUnit.SECONDS)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<Long?> {
                override fun onSubscribe(d: Disposable?) {
                    timerDis = d
                }

                override fun onNext(t: Long?) {
                    isClickBack = false
                }

                override fun onError(e: Throwable?) {
                }

                override fun onComplete() {
                }
            })
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
        super.onCreate(savedInstanceState)
        // requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT // 强制竖屏
        setContentView(attachLayoutRes())
        if (useEventBus()) EventBus.getDefault().register(this)
        AppManager.getAppManager().addActivity(this)
        initView()
        initData()
        start()
    }

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (ev?.action == MotionEvent.ACTION_UP) {
            val v = currentFocus
            // 如果不是落在EditText区域，则需要关闭输入法
            if (KeyBoardUtil.isHideKeyboard(v, ev)) {
                KeyBoardUtil.hideKeyBoard(this, v)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> {
                onBackPressed()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    protected open fun isLagerThan23(): Boolean {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
    }


    @SuppressLint("StringFormatMatches")
    public open fun requestLocationPermission(
        onLClick: () -> Unit = {},
        onRClick: () -> Unit = {},
        onPermi: () -> Unit = {}
    ) {
        if (isLagerThan23()) {

            locationDialog.setContentText(
                getString(
                    R.string.permission_info, getString(R.string.app_name),
                    getString(R.string.app_name), getString(R.string.permission_location)
                )
            )
            locationDialog.setCanceledOutside(false)

            locationDialog.setOnBtnClickListener(object :
                CustomAlertDialog.OnBtnClickListener {
                override fun onRightClick(v: View?) {
                    onRClick()
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(
                            this@BaseActivity,
                            Manifest.permission.ACCESS_FINE_LOCATION
                        ) || !ActivityCompat.shouldShowRequestPermissionRationale(
                            this@BaseActivity,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                        )
                    ) {
                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                        val uri = Uri.fromParts(
                            "package",
                            packageName, null
                        )
                        intent.data = uri
                        startActivityForResult(intent, 0)
                    } else {
                        requestLocationPermission()
                    }
                }

                override fun onLeftClick(v: View?) {
                    onLClick()
                    locationDialog.dismiss()
                    this@BaseActivity.finish()
                }

            })
            disposableLocationRequest = rp.request(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.CHANGE_WIFI_STATE
            )
                .subscribe(object : Consumer<Boolean> {
                    override fun accept(b: Boolean) {

                        permissinAllow = b
                        if (!b) {
                            if (!ActivityCompat.shouldShowRequestPermissionRationale(
                                    this@BaseActivity,
                                    Manifest.permission.ACCESS_FINE_LOCATION
                                ) || !ActivityCompat.shouldShowRequestPermissionRationale(
                                    this@BaseActivity,
                                    Manifest.permission.ACCESS_COARSE_LOCATION
                                )
                            ) {
                                locationDialog.show()
                            }
                        } else {
                            onPermi()
                        }
                    }
                })
        }
    }


    protected open fun doubleClickExit(act:Activity) {
        if (!isClickBack) {
            ToastUtil.show(act.resources.getString(R.string.press_back_again_exit))
            isClickBack = true
            timer()
        } else {
            AppManager.getAppManager().finishAllActivity()
            System.exit(0)
            finish()
        }
    }
    override fun onDestroy() {
        super.onDestroy()
        if (useEventBus()) EventBus.getDefault().unregister(this)
        CommonUtil.fixInputMethodManagerLeak(this)

        if (null != timerDis && !timerDis!!.isDisposed) {
            timerDis!!.dispose()
        }
        if (null != disposableLocationRequest && !disposableLocationRequest!!.isDisposed) {
            disposableLocationRequest!!.dispose()
        }
        AppManager.getAppManager().finishActivity(this)
    }


    public fun goActivity(cls:Class<*>, keys: ArrayList<String> = ArrayList(), values: ArrayList<*>? = null,needResult:Boolean = false,requestCode:Int = 8) {
        val intent = Intent(this,cls)
        for (i in 0 until keys.size) {
            values?.get(i)?.let { value->

                when (value) {
                    is Bundle->{
                        intent.putExtra(keys[i],value)
                    }
                    is Parcelable ->{
                        intent.putExtra(keys[i],value)
                    }
                    is Serializable ->{
                        intent.putExtra(keys[i],value)
                    }
                    is Boolean->{
                        intent.putExtra(keys[i],value)
                    }
                    is BooleanArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Byte->{
                        intent.putExtra(keys[i],value)
                    }
                    is ByteArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Char->{
                        intent.putExtra(keys[i],value)
                    }
                    is CharArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is CharSequence->{
                        intent.putExtra(keys[i],value)
                    }
                    is Double->{
                        intent.putExtra(keys[i],value)
                    }
                    is DoubleArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Float->{
                        intent.putExtra(keys[i],value)
                    }
                    is FloatArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Int->{
                        intent.putExtra(keys[i],value)
                    }
                    is IntArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Long->{
                        intent.putExtra(keys[i],value)
                    }
                    is LongArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is Short->{
                        intent.putExtra(keys[i],value)
                    }
                    is ShortArray->{
                        intent.putExtra(keys[i],value)
                    }
                    is String->{
                        intent.putExtra(keys[i],value)
                    }
//                    putExtra(String!, Array<(out) Parcelable!>!) defined in android.content.Intent
//                    putExtra(String!, Array<(out) CharSequence!>!) defined in android.content.Intent
//                    putExtra(String!, Array<(out) String!>!) defined in android.content.Intent
                    else -> {

                    }
                }
            }
        }
        if (needResult) {
            startActivityForResult(intent,requestCode)
        } else {
            startActivity(intent)
        }
    }
}